#include "threadPool.h"
#define BIG_FILE 1024*1024*100
//封装2个小火车函数，用于收发，在本 .c文件中，减少很多代码量
static int configureInit_puts_path(char *path){
    char str[256] ={0};
    FILE *configFile = fopen("/configure/netdisk.ini", "r");
    if (configFile == NULL)
    {
        printf("Failed to open the configuration file!\n");
        exit(-1);
    }
    for (size_t i = 0; i < 5; i++)
    {
        memset(str, 0, sizeof(str));
        fgets(str, 256, configFile);
    }
    memset(str, 0, sizeof(str));
    fgets(str, 256, configFile);
    str[strcspn(str, "\n")] = '\0';
    char *p = strstr(str, "=");
    if (p != NULL)
    {
        p++;
        sprintf(path, "%s", p);
        printf("path = %s",path);
    }
    else
    {
        printf("not found =\n");
    }
    return 0;
}
void send_train(int netfd, char buf[], int len){
    train_t train;
    memset(&train, 0, sizeof(train));
    train.length = len;
    memcpy(train.data, buf, train.length);
    printf("发送长度 train.length = %d\n", train.length);                                              
    ssize_t send_sret = send(netfd, &train, sizeof(int)+train.length, MSG_NOSIGNAL);
    printf("send_sret = %zd\n", send_sret);     
}                                               
void recv_train(int netfd){
    train_t train;                              
    memset(&train, 0, sizeof(train));           
    recv(netfd, &train.length, sizeof(int), MSG_WAITALL);
    printf("接收长度 train.length = %d\n", train.length);
    ssize_t recv_sret = recv(netfd, train.data, train.length, MSG_WAITALL);
    printf("recv_sret = %zd\n", recv_sret);
}

//服务端 响应 gets 命令，发送文件给客户端
int sendFile(int netfd, cmdInfo_t *cmdInfo){
    //到这里，表示服务端的这个文件确实存在
    //第 001 步，先把文件名拼接好，确定服务端要发送给客户端的文件位置
    char str[100] = {0};
    configureInit_puts_path(str);
    strcat(str, cmdInfo->fileName);
    // 第 002 步，根据路径名，再打开文件，发送文件名大小过去，是的，文件名大小
    int fd = open(str, O_RDONLY);
    if(fd = -1){
        printf("打开文件失败！\n");
        char buf001[] = "-1";
        send_train(netfd, buf001, sizeof(buf001));
        return -1;
    }
    //打开成功，则发送一个打开成功过去
    char buf002[] = "0";
    send_train(netfd, buf002, sizeof(buf002));

    struct stat statbuf;
    fstat(fd, &statbuf);
    cmdInfo->fileSize = statbuf.st_size;
    printf("cmdInfo->fileSize = %ld\n", cmdInfo->fileSize);

    //走到这里，正式开始发送 
    off_t total_size = 0;//维护一个变量，表示已经发送了多少数据量？
    int falg = 1;//维护一个标志位，用于断点续传

    while(total_size < cmdInfo->fileSize){
        printf("进入普通中小文件发送分支\n");
        train_t train;
        memset(&train, 0, sizeof(train));
        //读取文件内容，读一个 train.data 的大小
        ssize_t sret = read(fd, train.data, sizeof(train.data));
        //然后发送过去
        train.length = sret;
        printf("train.length = %ld\n", sret);
        send(netfd, &train, sizeof(int)+train.length, MSG_NOSIGNAL);
        printf("发送成功！\n");

        //经典关键先生 sret 
        memset(&train, 0, sizeof(train));
        recv(netfd, &train.length, sizeof(int), MSG_WAITALL);
        sret = recv(netfd, train.data, train.length, MSG_WAITALL);
        if(sret == 0){
            break;//收到最后一个数据包，为 0
        }
        if(sret == 2 && strcmp(train.data, "0") == 0){
            //表示这次发送，客户端并没有接收到数据，至少表示有问题
            continue;
        }
        total_size += 1000;
    }
    close(fd);//记得关闭文件描述符号
    return 0;
}

//服务端 响应 puts 命令 ，接收客户端的文件
int recvFile(int netfd, cmdInfo_t *cmdInfo){
    // 第 001 步，接收
    printf("正常接收！\n");
    //记录现在已经收了多少文件量
    off_t total_size = 0;
    //设计标志位
    int flag = 1;
    //先拼接文件路径，用于打开，然后读入
    char str[200] = {0};
    configureInit_puts_path(str);
    printf("\n");

    strcat(str, cmdInfo->fileName);
    printf("str fileName = %s\n", str);
    //打开文件，准备捉妖！
    //str[strcspn(str, "\0")] = '\0'; 
    //但是，这边有失败风险
    int fd = open(str, O_RDWR|O_CREAT, 0666);
    printf("fd = %d\n", fd);
    printf("cmfInfo->fileSize = %ld\n", cmdInfo->fileSize);
    
    while(total_size < cmdInfo->fileSize){
        train_t train;
        printf("进入接收！\n");
        memset(&train, 0, sizeof(train));
        recv(netfd, &train.length, sizeof(int), MSG_WAITALL);
        if(train.length == 0){
            break;//最后一个包为0，火车头自然也为0
        }
        ssize_t sret = recv(netfd, train.data, train.length, MSG_WAITALL);
        printf("收到 %ld 个字节！\n", sret);
        
        //关键先生到位，接收出现错误，便返回 -1 ，直接重新接收
        if(sret == -1){
            flag = 0;
            char buf[] = "0";
            send_train(netfd, buf, sizeof(buf));    
            //然后，接收客户端返回
            recv(netfd, &train.length, sizeof(int) ,MSG_WAITALL);
            recv(netfd, train.data, train.length, MSG_WAITALL);
            if(strcmp(train.data, "0") == 0){
                flag = 1;
                printf("flag 已经修改为 1.\n");
            }
            continue;
        }
        else if(sret == 1){
            printf("接收完成！\n");
            return 0;
        }
        //走到这里，表示接收没出问题，需要发送一个信息给客户端
        char buf002[] = "ojbk!";
        send_train(netfd, buf002, sizeof(buf002));
        sret = write(fd, train.data, sizeof(train.data));
        printf("write ret = %ld\n", sret);
        total_size += 1000; 
    }
    //train_t train;
    //memset(&train, 0,sizeof(train));
    //recv(netfd, &train.length, sizeof(int), MSG_WAITALL);
    //recv(netfd, train.data, train.length, MSG_WAITALL);
    //printf("服务端接收上传完毕！\n");
    close(fd);
    return 0;
}

